package com.inspur.edp.commonmodel.engine.api.data;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.collection.GspFieldCollection;
import com.inspur.edp.cef.designtime.api.element.GspAssociation;
import com.inspur.edp.cef.entity.entity.ICefData;
import com.inspur.edp.cef.spi.jsonser.abstractcefchange.BefDateSerUtil;
import com.inspur.edp.cef.spi.jsonser.base.StringUtils;
import java.io.IOException;
import java.util.Date;
import java.util.Map;

public class AssoInfoJsonSerializer extends JsonSerializer<AssociationInfo> {
private static ObjectMapper defaultMapper = new ObjectMapper();
  @Override
  public void serialize(AssociationInfo associationInfo, JsonGenerator jsonGenerator,
      SerializerProvider serializerProvider) throws IOException {
    if (associationInfo == null) {
      jsonGenerator.writeNull();
    } else {
      jsonGenerator.writeStartObject();
      if(associationInfo.getAssociation() == null) {
        serializeCore(associationInfo, jsonGenerator, serializerProvider);
      } else {
        serializeCoreWithAsso(associationInfo, jsonGenerator, serializerProvider);
      }
      jsonGenerator.writeEndObject();
    }
  }

  private void serializeCore(AssociationInfo associationInfo, JsonGenerator jsonGenerator,
      SerializerProvider serializerProvider) throws IOException {
    for (Map.Entry<String, Object> pair : associationInfo.getValues().entrySet()) {
      jsonGenerator.writeFieldName(StringUtils.toCamelCase(pair.getKey()));
      Object value = pair.getValue();
      if (value instanceof Date) {
        if (value == null) {
          jsonGenerator.writeNull();
        } else {
          jsonGenerator.writeString(BefDateSerUtil.getInstance().writeDateTime((Date) value));
        }
      } else if (value instanceof ICefData) {
        jsonGenerator.writeRawValue(defaultMapper.writeValueAsString(value));
      } else {
        serializerProvider.defaultSerializeValue(pair.getValue(), jsonGenerator);
      }
    }
  }

  private void serializeCoreWithAsso(AssociationInfo associationInfo, JsonGenerator jsonGenerator,
      SerializerProvider serializerProvider) throws IOException {
    GspAssociation gspAssociation = associationInfo.getAssociation();
    GspFieldCollection fieldCollection = gspAssociation.getRefElementCollection();
    if(fieldCollection == null || fieldCollection.isEmpty()) {
      return;
    }
    for (IGspCommonField field : fieldCollection) {
      jsonGenerator.writeFieldName(StringUtils.toCamelCase(field.getLabelID()));
      Object value = associationInfo.getValue(field.getLabelID());
      if(value == null) {
        jsonGenerator.writeNull();
        continue;
      }
      switch(field.getMDataType()) {
        case DateTime:
          jsonGenerator.writeString(BefDateSerUtil.getInstance().writeDateTime((Date) value));
          break;
        case Date:
          jsonGenerator.writeString(BefDateSerUtil.getInstance().writeDate((Date) value));
          break;
        default:
          serializerProvider.defaultSerializeValue(value, jsonGenerator);
      }
    }
  }
}
